#ifndef _USER_INCLUDE_H_
#define _USER_INCLUDE_H_

#include "include.h"
#include "motor_config.h"
#include "tx8C1200_adc.h"
#include "tx8C1200_timer.h"
#include "typedef.h"

typedef union _u_16 {
    u16 w;
    struct {
        u8 h;
        u8 l;
    } b;
} TYPE_U16;

typedef union _s_16 {
    s16 w;
    struct {
        u8 h;
        u8 l;
    } b;
} TYPE_S16;

typedef union {
    u8 flag;
    struct {
        u8 f_over_v_done      : 1;
        u8 f_under_v_done     : 1;
        u8 f_st_bemf_done     : 1;
        u8 f_overcurrent_done : 1;
        u8 f_phase_loss_done  : 1;
        u8 f_no_load          : 1;
//        u8 f_stop_done        : 1;
        u8 reserve            : 2;
    } bits;
    
} TYPE_FAULT;

typedef s16 _iq;

typedef struct _DW {
    TYPE_S16 MSW;
    TYPE_U16 LSW;
} TYPE_DW;

typedef union _DW32 {
    s32 d32;
    struct {
        TYPE_S16 MSW;
        TYPE_U16 LSW;
    } d16;
} TYPE_DW32;

typedef enum {
    WORK_STA_IDLE = 0,   // 0
    WORK_STA_OFF,        // 1
    WORK_STA_ISD,        // 2
    WORK_STA_BRAKE,      // 3
    WORK_STA_ALIGN,      // 4
    WORK_STA_IPD,        // 5
    WORK_STA_CLS,        // 6
    WORK_STA_OL,         // 7
    WORK_STA_RUN,        // 8
} T_WORK_STA;


#define _IQ(n)        ((n)*16383)
#define _IQ15(n)      ((n)*32767)

#define ABS(n)        ((n)>0?(n):(-n))

#define MDU_ABC_SHIFT(op1_addr, op2_addr, res_addr, shift_bits) do {MDU_ADR0 = (u8)(op1_addr); \
                                                                    MDU_ADR1 = (u8)(op2_addr); \
                                                                    MDU_ADR2 = (u8)(res_addr); \
                                                                    MDU_CTL1 = (u8)(shift_bits);} while(0);

#define MDU_AC_SHIFT(op1_addr, res_addr, shift_bits)            do {MDU_ADR0 = (u8)(op1_addr); \
                                                                    MDU_ADR2 = (u8)(res_addr); \
                                                                    MDU_CTL1 = (u8)(shift_bits);} while(0);

#define MDU_BC_SHIFT(op2_addr, res_addr, shift_bits)            do {MDU_ADR1 = (u8)(op2_addr); \
                                                                    MDU_ADR2 = (u8)(res_addr); \
                                                                    MDU_CTL1 = (u8)(shift_bits);} while(0);

#define MDU_C_SHIFT(res_addr, shift_bits)                       do {MDU_ADR2 = (u8)(res_addr); \
                                                                    MDU_CTL1 = (u8)(shift_bits);} while(0);


#define MDU_ABC(op1_addr, op2_addr, res_addr)                   do {MDU_ADR0 = (u8)(op1_addr); \
                                                                    MDU_ADR1 = (u8)(op2_addr); \
                                                                    MDU_ADR2 = (u8)(res_addr);} while(0);

#define MDU_AB(op1_addr, op2_addr)                              do {MDU_ADR0 = (u8)(op1_addr); \
                                                                    MDU_ADR1 = (u8)(op2_addr);} while(0);

#define MDU_AC(op1_addr, res_addr)                              do {MDU_ADR0 = (u8)(op1_addr); \
                                                                    MDU_ADR2 = (u8)(res_addr);} while(0);

#define MDU_BC(op2_addr, res_addr)                              do {MDU_ADR1 = (u8)(op2_addr); \
                                                                    MDU_ADR2 = (u8)(res_addr);} while(0);

#define MDU_A(op1_addr)                                         do {MDU_ADR0 = (u8)(op1_addr);} while(0);

#define MDU_C(res_addr)                                         do {MDU_ADR2 = (u8)(res_addr);} while(0);

#define DIV_16_16               (0 << 1)
#define DIV_32_16               (1 << 1)
#define MUL_16_16               (2 << 1)
#define SQRT                    (3 << 1)
#define SUB_16_16               (4 << 1)
#define ADD_16_16               (5 << 1)
#define SUB_32_32               (6 << 1)
#define SHIFT                   (7 << 1)

#define MDU_CTL0_ADDR0H         (1 << 7)
#define MDU_CTL0_ADDR1H         (1 << 6)
#define MDU_CTL0_ADDR2H         (1 << 5)

#define MDU_SIGNED_OP           (1 << 4)
#define MDU_UNSIGNED_OP         (0 << 4)
#define MDU_LEFT_SHIFT          (0 << 5)
#define MDU_RIGHT_SHIFT         (1 << 5)
#define MDU_CTL_EN              (1 << 0)

extern data TYPE_DW MUL_RES_1;
extern data TYPE_DW MUL_RES_2;
extern data TYPE_DW MUL_RES_3;
extern data TYPE_DW MUL_RES_4;        // 16 Bytes

extern data u8 shift_bit;

// main
#define UART_TX_LEN     (10)
extern xdata u8 uart_tx_buf[UART_TX_LEN];

extern xdata T_WORK_STA work_sta;

extern bit   time_1ms_flag;
extern bit   run_sta;

extern u8 cnt_Bt;

#endif
